#include "../common.h"

class Any
{
public:
    class holder
    {
    public:
        virtual ~holder(){}
        virtual const std::type_info& type() = 0;
        virtual holder* clone() = 0;
    };

    template<class T>
    class placeholder: public holder
    {
    public:
        placeholder(const T& val):_val(val){}
        virtual const std::type_info& type(){ return typeid(T);}
        virtual holder* clone(){return new placeholder<T>(_val);}

        T _val;
    };
    holder* _content;
public:
    Any& swap(Any& other){std::swap(_content, other._content); return *this;} // Any类内部的swap的参数只支持Any类对象
    // 获取一个_val对象的指针
    template<class T>
    T* get(){ assert(typeid(T) == _content->type()); return &((placeholder<T>*)_content)->_val;}

    Any():_content(nullptr){}
    template<class T>
    Any(const T& val):_content(new placeholder<T>(val)){}
    Any(const Any& other):_content(other._content ? other._content->clone() : nullptr){}
    ~Any(){ delete _content;}

    template<class T>
    Any& operator=(const T& val){ Any(val).swap(*this); return *this;}
    Any& operator=(const Any& other){ Any(other).swap(*this); return *this;}
};

int main()
{
    Any a1(1);
    Any a2;
    a2 = std::string("Hello World");
    // Any a3("NiHao");
    std::cout << *(a1.get<int>()) << std::endl;
    std::cout << *(a2.get<std::string>()) << std::endl;
    // std::cout << *(a3.get<const char*>()) << std::endl;
    a2._content->type();
    a1 = 333;
    // std::cout << *(a1.get<int>()) << std::endl;
    return 0;
}